{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$X=\\begin{pmatrix}\n",
    "X_1^{(1)} \\ \\ X_2^{(1)} \\ \\ X_3^{(1)}\\ \\ \\ldots \\ \\ X_n^{(1)}\\\\\n",
    "X_1^{(2)} \\ \\ X_2^{(2)} \\ \\ X_3^{(2)}\\ \\ \\ldots \\ \\ X_n^{(2)}\\\\\n",
    "X_1^{(3)} \\ \\ X_2^{(3)} \\ \\ X_3^{(3)}\\ \\ \\ldots \\ \\ X_n^{(3)}\\\\\n",
    "\\cdots \\ \\ \\ \\cdots \\ \\ \\ \\cdots \\ \\ \\ \\cdots \\ \\ \\ \\cdots \\\\\n",
    "X_1^{(m)} \\ \\ X_2^{(m)} \\ \\ X_3^{(m)}\\ \\ \\ldots \\ \\ X_n^{(m)}\\\\\n",
    "\\end{pmatrix}\\ \\ \\ \\   $\n",
    "$W_k=\\begin{pmatrix}\n",
    "W_1^{(1)} \\ \\ W_2^{(1)} \\ \\ W_3^{(1)}\\ \\ \\ldots \\ \\ W_n^{(1)}\\\\\n",
    "W_1^{(2)} \\ \\ W_2^{(2)} \\ \\ W_3^{(2)}\\ \\ \\ldots \\ \\ W_n^{(2)}\\\\\n",
    "W_1^{(3)} \\ \\ W_2^{(3)} \\ \\ W_3^{(3)}\\ \\ \\ldots \\ \\ W_n^{(3)}\\\\\n",
    "\\cdots \\ \\ \\ \\cdots \\ \\ \\ \\cdots \\ \\ \\ \\cdots \\ \\ \\ \\cdots \\\\\n",
    "W_1^{(k)} \\ \\ W_2^{(k)} \\ \\ W_3^{(k)}\\ \\ \\ldots \\ \\ W_n^{(k)}\\\\\n",
    "\\end{pmatrix}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$X \\cdot W_k^T = X_k$\n",
    "\n",
    "$(m*n) \\cdot (n*k)=m*k$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 反向操作 $X_k \\cdot W_k=X_m$ 可以恢复成原始维度的矩阵,\n",
    "#### 但是$X_m$和$X$是不一样的, 因为数据在降为的过程中是有信息丢失的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.empty((100,2))\n",
    "x[:, 0] = np.random.uniform(0., 100., size=100)\n",
    "x[:, 1] = 0.75 * x[:,0] + 3. + np.random.normal(0, 10., size=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PCA(n_components = 2)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from c16_PCA import PCA\n",
    "\n",
    "pca = PCA(n_components=2)\n",
    "pca.fit(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.76961081,  0.63851327],\n",
       "       [ 0.63851906, -0.76960601]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca.components_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 降维度操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PCA(n_components = 1)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca_1 = PCA(n_components=1)\n",
    "pca_1.fit(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 1)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_reduction = pca_1.transform(x)\n",
    "x_reduction.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 2)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 恢复\n",
    "x_restore = pca_1.inverse_transform(x_reduction)\n",
    "x_restore.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD8CAYAAABn919SAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzt3Xt0W9Wd6PHv1tt2YltJbOfhmEdIQiA1JDdAoJQE0g5lpgNcT9pV7txeOmQNa5Jh6MyQ2xdw6660lHbClDK04bIKlOm0pa2rArcvSnm2TQLNq6pDCEkDiDhx7BC/4pde+/6xJSw7si3ZR7J0/Pus5WXr6ETaR8r6aeu3f3tvpbVGCCFE8XNMdQOEEEJYQwK6EELYhAR0IYSwCQnoQghhExLQhRDCJiSgCyGETUhAF0IIm5CALoQQNiEBXQghbMKVzyebM2eOPvvss/P5lEIIUfR27959UmtdNd55eQ3oZ599Nrt27crnUwohRNFTSr2dyXmSchFCCJuQgC6EEDYhAV0IIWxCAroQQtiEBHQhhLCJvFa5CCFEoQsGIRCAUAjq6qChAerrp7pVmZEeuhBCJASDsHUrdHRAba35vXWrOV4MJKALIURCIAB+v/lxOIb+DgSmumWZkYAuhBAJoRBUVAw/VlFhjhcDCehCCJFQVwddXcOPdXWZ48VAAroQQiQ0NJi8eUcHxONDfzc0THXLMiMBXQghEurrYfNmkzc/etT83ry5eKpcpGxRCCFS1NcXTwAfSXroQghhExLQhRDCJiSgCyGETUhAF0IIm5CALoQQNiEBXQghbELKFoUQwmpTtGSj9NCFEMJKU7hko/TQhRBisoJBWrcFOL4zhO/4EcJz5jP3A35qHJjppmB67DnupUsPXQghJiMYpOPOrfzxxQ5a3bXMjrUxu7WZ5udaOXEicU6elmyUgC6EEJMRCHCwzU+83E9JqYPesmqcTgd1va9z4EDinDwt2SgpFyGErVk6PpnuwUIhTgzWUp5YR/3knGUsDP2e8nAbr3XGoaPL5NE3bLDsmkaTUQ9dKfUvSqn9SqlmpdQPlFI+pdQ5SqlXlFKHlFI/VEp5ct1YIYTIhqXjk6M9mNdLjbeLgQFzWu+MGk7UvI9uTzV1Kr9LNo4b0JVSC4DbgVVa6+WAE/g48FXg61rrxUAHkPuPHyGEyIKlW8qN9mBas7S6A0d3B/19cbx9HQxGnTy24gGcjz8KjY15W74x05SLCyhRSkWAUuA4cA3wPxL3Pw40AtusbqAQQkxUKGQ606nSjU9mlJYZ8WAnTsCB1ypwHjvKn9ZtZk1JgPChEG/rOo6t2cDHN9XnfRnecQO61rpFKbUVCAH9wK+B3UCn1jqaOO0osCDdv1dK3QrcClBXLPs4CTGNTNEcmLyoqzOZkWTlIJw5PpnMpPj9sNIdZNEvA3T+V4jWD9Uxd2PKi5HyYCdOwPbt4FddRObXcdBbz05fPZsfhxun8LXLJOXiB24AzgHmA2XAdWlO1en+vdb6Ya31Kq31qqqqqsm0VQhhsSmcA5MXmWwpl8ykLB0McuXOrfjpoHdWLW/tGfFipDzYgdfi+FUHlbqD15c1TC6VY6FMUi4fBN7UWrcDKKUCwBVApVLKleil1wLHctdMIUQupKaFIXdzYKbqW0ByS7nU596wYfhzx/YFuaEjwLKDTxJ1emmdtxJfmYMT3X7wM/RipDyY81iIyPw6ti/bQNtc82B5KjUfUyYBPQSsVkqVYlIu64BdwAvAeuAJ4GbgqVw1UgiRG5nmmCcjNaWR+i0gX3t1jrmlXFMTm3ZugXCEGeFT9JbMYeE72zlcfQUVs2vOfDESD/Yc46dypsK4KRet9StAE7AH+FPi3zwMfAb4V6XUYWA28EgO2ymEyIG6OhOIUlkdmCytNLFSMAhbtlBRoeh0VxHFyYzTrcSicWa3HWDZMkZ9MTJJ5UyFjKpctNZfAL4w4vAR4FLLWySEyJuGBtNbBtMZ7crBHJhsvwXkLT0TCEAkQuncKhbOVHS1zGNmx1vMCJ9i1hwnJZ6OUV+MTFI5U0FmigoxjeUjMGVSaZKUs/RMMAjbtsHOnaA1rF4Nra1QVQUDA8yYUcKMpTOg5yzzQpQq04gxXowxUzlTRAK6ENNcrgNTNt8CLB+kDQbhW9+Cn/8c+vvpr5zLu/2lOH7wEm5XDM+yRVQMdJpzfT6IxWD+fHj88cKL1hmQxbmEEDmV/Bbg98PRcWbCh0Im6Kea8CBtsru/dy/E40S0i/DRduKROLEZ5YTx0rn/GKcWXGiCeXu76b3ffXdRBnOQHroQIg8y/RaQaXomozx7srsfDkM0Sm/UB64oM8Mn6So5C5d7kK7SsznSt4SrF/ng6qvTPlAxTbySHroQomBkUj2S8WSoZHe/ogJcLuKRKNrpwhUdwBUdIOr0cnLhxXz33EZ4NP2aK8U28UoCuhCiYGSSnhlZBrl0MMhNBxuJ3XyLCcrJaJusyTz/fCgrw8sgzvAAceXEO9hNb1kVry5oGLNEs2BLLkchKRchREEZLz2TWgZ5/v4m1ry8BUc8QoezCt4YGCqLSY7G+v1w9dWo57ejQi30ufy8fdYaXli6iddc9Wweo3Y8HxOvrCQBXQhRVOrqYOErTVy7715q2v5E3OniVNlZzPAMwP79cOGFpgvd2DisJrP0b/+GN5Y38P3mekIh8HqhVMP994+eG8+m5LIQSEAXQuRErgYTPzmziZLffhpfvI+4ckIcZncfIT5rEfhmQEuLqVqBM7r7S4DG9cPr3aurR693z8fEKytJQBdCWC4ZMGMxkwvfuRN++lNTEbh+/dA5GQf8lJPPfv55BuZ4iZyEqHLjcsRxOhSed1ug9iJTfnj11WO2L9N690KdEToaCehCCMsFAiaYNzebznJVlendbtkCS5aYczKeETpy+mhnJz6PB1+5C6Je6OsDpWBgwDyJ2z3uoirZ5MYLcUboaCSgCyEsFwqZnrnPByUl5lhFhek8JytEMp4ROrI7XVkJvb1mEpDDAaWl0NtLDAdtrZqfLLubk4F6Ghg9EGe7HIHUoQshpq26OhO8k6lsMB3oqioTGLOaETry5EsugWgUBgfNNH2HgygO/lD9ER6/5ru0fWD9uPXima6WKHXoQohpr6HBZD66ukxHur/fBPQFC0ywT7dsb+nhIJ840gi3jFJPnnThhWZxrfJy6OmB88+n6S8f4wf//UcMLKnPqF480+UIpA5dCDHt1debAdAtW0xPvaoKFi0Cl2uoF5xaPVJ62Gz/tvTyNEn1dKUmVVXw1a++F4F/fQvUZrkGTCa5calDF0IITDXLkiWj55/vuj5I573bqDmyk1nh47jmVlFSfuVQVxjS1pOnKzXJVb241KELIUTCGb3gYBA2boMXXmDJsWOmOqW2Ftpi0HEMnnsO1q2DmhHbv43Tnc5VvXix1aFLDl0IkR/BINx5J7z4InR3m7rGwUGz0YTbbfIxvb1w4IA5P4uucDZL9GYjV4+bK9JDF0LkXjAIt99upuZ7PGZJW6VMIA+HzTEwf3d2DpWdZNEVzrZePNNyxGKqQ5ceuhAid4JB2LjRRMv9+02vHEzZi9bDf6qqTGBXKudd4WIrR8yU9NCFELmRjJoHD8KsWSaId3SA0wllZabkUGtz2+k0wX7FCrjnnpx3iS3f6q5ASEAXQlgrmct48kmzpGFXlxnknDfP5Mh7e81sT6/XnB+PmwC/Zg1s2pSXiFps5YiZkoAuhLBGUxPcey+88QbMnGny48mlDN1umD3bFKO//TZEImYa6Y035i2Ipyq2csRMSUAXQkxOMGhmEP3qV6a3XVJipua/+66pXKmuhrY2s+aK02mC+tKlU1ouUmzliJmSQVEhxMQl8+Tbt5uAnZzn73Sa262tJsBXVprzT50yefIprv0rtnLETEkPXQgxccnRxYEBkwcfHDTplL4+s9ZKV5epWiktheuuK6ilCoupHDFTEtCFSKOYlkydUsnRxZkzTc+8tNQE8XDYBPcZM6Y8vTKdSMpFiBHsWqOcE8mVEC+5xATxWMwEdaVML/2KK4YF82DQLM0yckFFYQ0J6EKMUOhLpuYtKGbyRMmFxefPN2uwuFymZ75sGTz2GPz4x8OCuXxQ5lZGKRelVCXwbWA5oIFbgIPAD4GzgbeAj2mtO3LSSiHyKNc1ypNJ54zcjW3Mrdsm04ZMnyh1082eHvj7vx/1gjKZzCOprsnJtIf+DeBXWuvzgYuAA8Bngee01ouB5xK3hSh66TZfsKpGebK9VCu+PYzZhjvuMBUpK1bAE0/Aq6+O/0T19aYH/+ij5vcoEXjfPvPz1FNmfa7W1uEflNKDn7xxA7pSqhy4CngEQGsd1lp3AjcAjydOexy4MVeNFCKfMt2ebCImG5Cz2rotyzZ03XoHfOMbpmJFKZMPf+UVeOaZiT1RimAQ3nzTfDCWl5vx0x074PDhoQ/KQk91FYNMeujnAu3AY0qpvUqpbyulyoAarfVxgMTv6hy2U4i8yWWN8mQDshXfHka2obo1yA37Gln96n+YA8mlbJ1OE1n37p3YE6UIBGD5clOmPjBgJokqZdbrSn5QWvFhNd1lkkN3ASuBf9Jav6KU+gZZpFeUUrcCtwLUFfu8WjFt5KpGebJTzq2Y4ZjahurWIFfs2Eqn8uPQMVAOM6jpcpmvJ0qZuvIJLGebKhQyE0TLy81y511dpv1+/9DrbNfp+PmUSUA/ChzVWr+SuN2ECegnlFLztNbHlVLzgLZ0/1hr/TDwMMCqVau0BW0WomgtX25myUciZrXY2lrTEc40TqaOQY6yG9u4Uj8UrjoQoFP56dB+0zOPR00Qj8fN4ln9/cQcTl7+o5/nKzfgDNSTzDxlM3iZDNY1NeYHzgzedp2On0/jBnStdatS6h2l1FKt9UFgHfBa4udm4N7E76dy2lIhilwwCE8/bTatb2kxmyd3dprNlLMJyJP99pD6oeA+FiI2v5YrLgBn6QqTM9faBHQgruGXi/6JZy9qZGAA9v0SHnnEzOa/5BLT686k0ibTYF1aCi+9ZD5TVq/OLtUlFTKZzxT9J+B7SikPcAT4O0z+/UdKqQ1ACPhobpoohD2kDvotWWKOdXRAc7PZUDlTVgSuoQ+FlDzHtdeaO3fvNgOiPh+/v3gDz152H+Ew7Nxpct/xuNlBrrnZpFCSPe6x1hIf75tFapXk9dcPBfxsXhMryjmLXUYBXWu9D1iV5q511jZHCPuyor4968A1XvQf2XW+9FJYvPi9B3zsFqitgJdfNsE8FjPfKqJRs6x5S4tJIy1dOv51jPXNYrIbTth1w4psyUxRIfLEigqVrEr7MinsHqekJ9nmri4TxN95xwT1eNz8nD5tVsl9+eWhbUEnYrIVLlIhY8jiXELkiRWDfhn18kfuGLRy5VD0hzO7rWN0nZNt9nhMMAfzUDpR3uB2mxVxy8tN3nuiRqtw8XrNXKXx0ktSIWNID12ICZjIeipW1LeP1stf5Uk06MYb4ROfgEOHzJ1am7XKT5wwt7PstibbvHKl6Y27XGZAtLzc3O/xmB77VVeZaseJSjeZ68gR8yGSyczRXE4GKyZK6/xVEq5atUrv2rUrb88npod8Vzek5rFTe9r5GIBL99zn7mni1hNbKHEl1iH3eEzUdbtNTSSY22vXDnVjGxuzfu6NG2HPHrODnNNptgh1Os1DX3TRhB922LWlvo+traaHntrrHqv5dq5yUUrt1lqnG8ccRlIuoqhNRXXDVA7AJXvMv/tWkPlPB1jav49FJ3fgmV0BVfPgtdfMvHqPxwT0gQETFTs7Jz05aONG89ouWmQqXKJRs2LueedZUy8+MvNzyy1m97pUY33BsOOGFdmSgC6KWr6Ca2rvb88euOyy4ffncwCuniD1fVthjR/2dUB7ZGiRlLIyE9BPnzYB/fLLzdR9pcyLk+0spNTnTSk97OsznxGVlaYoJhe9YcmLZ08CuihquV7qFs78FrB/v6nqWLMG5s415+Q10KR+inV3m92CBgbg5EmYM8dcfHc3nHWW6Z1buGNQPnvBMnM0ezIoKopaLpe6TRpZKrhypTm+d2+eBuBGjsDu2zdUo1dRYXrmWpvC8LIy01C3e6jRRTq7xq4bOeeS9NBFUctHL27kt4CaGlPV8eqrJtCkW08lGIRvfcvMrkxOY9+4cQLBKN0gwZtvmsC9eLHZGWj7dnP/4KBZT8Dng29+M7vppwVK8uLZkYAuipoVi1WNJ10u1+eDG24Yvdri85+HP//ZZEPAbOhw9Ch8+ctZti3dIMGFF5pRyTlzzApfy5eb28uWwcUXZ5zQtnNVSCbseP0S0EXRy3UvLttvAYGA6SiXl5uSPjC99La2CQzWphskOO88Myrp95v7Fy+Gz3wmqwee7muf2PX6JaALMY5svwWEQib7kToV3eczHwRpB2uDQdi2zeRntDb5mU2bzBOMVupx8cWTKvqe7muf2PX6JaALkYFsvgXU1ZlKmIGBoR56shz8jMHaYBDuvNPsxZbMz7z0ksnP3HNPzgYJ8lEdVMjsev0S0EXBK8Rc51htamiAXbtMDj05Ebunx2RK3quEaWqCBx80DxSNmpHW0lJzn1ImZxMImF54DgYJpnuNt12vXwK6KGiFmOtM16Y774QFC8zMybo6+OQn4Te/GapyWbs2UeVCEP5i89AuDsnNmN95x5QaVldzOuqjp6WLw98L8RzQ0FBPfaO1Fzvda7ztev1Shy4KWiHuBD+yTeGwyZjs3TsU4J9+2qTB9+0zx7dtSwTzO++E3/3O/EO32/TOYzHzwMeOcfo0tL49wABeIvPrxlyQajKme423Xa9feuiioFmd67QifTOyTQcOmPR3OHzmKrXlzzah/+NBSk614HVEKJnpwhePm7VWkkF9cNAE9v5+Oo/3MSPWQ+esRby+rCGng3XJcYHka3L//YWT0soHO9a4Sw9dFDQrZ4Jmst/DRNqU/Du1qmXxQJB1//ejVH/m75h14gCx0pm4+7txtoSIaTXUK3e7TXB3OsHtJtof5u1z1/D8NffQNrf+vcfN1WCdVa+JKAwS0EVBs3Kda6vSNyPb5PGYQc/zzzf3n7+/iRt/8glWnfg5DuI4HZqKnhbiHh9x5SQW1SagRyLmt1JmQPQ73+E7t+/j+1c+9F4wh9wO1hViSktMnAR0UdCszHVatU3ZyDatXGmWlD27O8jaH27kup/eiqfjBErH0FrhifQCGjRE3SUoHTcjqMkEfEkJ3HUXrF+f940aZOs2e5Ecuih4VuU6sy1VGyvfPrJNbzQFeffzW/G9fZC4duDyOnH0a2LxKDGHG2dsEO1y0OOrosTto6K83CTeUycRkZ+lDCbzmojCJgFdTBvZlKplWy65pDnATr+fqo4whMtwxaOEXWV4oz2Eo07c8Shh5UMRoeOLD1Bxx+gLZ8kStWKiJKALWxqtdz1a7zfd9mdZTQ0PhTgxWEtNaQWDKsqM3jbi3hLCxNHRGBCnx7+Q6B2f5ewxgnm+5fsbgcgt2VNU2E62e36mO//nP4d168y+mUlzjgdZ9tI21vGC2a6nvByuucakTAIBdv6yg2hfmPPatoOOU9J/Ckc0zOmK+cx78O5JLWdbiLNlRf5kuqeoDIoK28m2ciP1/LY2+OMfTVD/2c9MTx1M5cpHf7ie9x/5L7NLcjgMp07BM8+YtXKXL2dpdQe9UQ+Hq1YTcZcSdpTwysK/oefB7046mEtpociEBHRhO9lWbiTPb22FHTvMlpwLF5ptOY89YypXPvL/bqW8pwW3ig5Vpyhlfre3Q3Mz/i9v5qK1fsrcEXZXXcePbwpQ3fQQS9ZPristpYUiU5JDF7aTbeVG8vzXXzfL3JaUwKLeIF9RW1gdeg53fAC3iuF0gSMWA5d3KKg7nWamZygE9fXM3VbPXGCFhddj15UBhfWkhy5sJ9ta7uT5bW1midv5J4PcGrqTKwZeQPncZhKnI4YjFjX/IBIxvfNIxAT0tOviWicf+6YKe5Aeuig6ow0Qph4vKzMd59H2/EyVrPS4/XYT1P+uL0Cdrw0VVYSVD7drEJQ2AVxr8ymRTLl4PGYbuJztEC2lhSJzGQd0pZQT2AW0aK0/opQ6B3gCmAXsAT6htQ7npplCGKPVh19/vVnhMHl8vMqWYQ8YCFAfCvHEsjoemNHAsiMhSvoHGXSWQTSCa2Yp9EXA5TIBXSnzu6oKrr122MSgXJDSQpGpbHronwIOAOWJ218Fvq61fkIp9RCwAdhmcfuEGGa0rcMefBAuumjsuvGRPfuNR+6g5icPmZ53aSlzly/nf/uPcKi0jL52L8o3g9nxk7g9TqDU7OPp9cLHPjYsiAeDEGjMbUmhHVcGFNbLKIeulKoF/gr4duK2Aq4BmhKnPA7cmIsGCpFqtAqWlpaxK1tSS/9WuoN89JEPMee7XyfePzC0hO2rr+LvOMKlqzSLVlczd04M99zZ5gEiEbP+ysMPw0MPDQvmUlIoCkWmg6L3A58G4onbs4FOrXVilIijwAKL2ybEGUYbIFywYOyBw2TPfulgkCt3bmXRiZ1oFHHlNPlwl8sMcDY3m9tf/rLZZiiZI//4x822cSPqyaWkUBSScVMuSqmPAG1a691KqbXJw2lOTTvlVCl1K3ArQJ0My4tJGm2A8LbbTA595PENG4BgkIufDFBHCH/nEbpnzMcZD6OV0/yvTVaseDwmrVJXZ3rg28bPIGZSUiizPEW+ZNJDfz9wvVLqLcwg6DWYHnulUir5gVALHEv3j7XWD2utV2mtV1VVVVnQZDGdjbac7vr1oyyzi8mJzPV2cMJTS1lvGzXtzcSUmzgKR7JrEouZnrnbnVXFynglhZKSEfk0bg9da/054HMAiR76Zq313yqlfgysxwT5m4GncthOId4z1tZpjY2Jk5J3PvkkeL0sPmslLx900OWppizaSXdJNf7TR8GpQMdNKaJS8I//mFX3ebySwtEGcXOxpZwQk5lY9BngX5VShzE59UesaZIQ4xuz55t6J4DWzD64nauWnqBz3jKi4Th4ffRfehVOr8ecU1MDX/kK3HdfVu0YbwMO2UBC5FNWE4u01i8CLyb+PgJcan2TRD4Va353ZM936WCQcw4GiN0cgoojMH++ubOy0izO4vMxu+0Asz+yFg69z5TFnFsHH75y1IvO9LUZq6RQNpAQ+SRT/6exYs7vpvZ8q1uDXLFjK5W6g5CuNdM9m5vNalvnnw8DA2YiUGenuUinEx54AB591ORoRgnmVrw2+d5STkxvEtCnsWIuuUsdjFz2eoABn59O5aei0gHV1eaCXn8d5s6Fyy83+XGlMt6U1KrXxso9UYUYj6zlMo0V8yp+wwYjO0Oc8NQyMGg2bIZl8Pvfm556PG5mdy5dmlUktfK1kVmeIl+khz6NFfMqfqk93xB1+FUXV1xhxjapqYH3vc/01CfYLS7m10ZMX9JDn8aKfRW/93q+yQvxAPHEhSTz5BPsGhf7ayOmJ9lTdJrLRZXLlFTO5OBJi7UCSNhPpnuKSkAXlsp2g2YhxPgyDeiSchGWSPZmn3rKLImyYsVQdQjIzEgh8kECuhhVpimH1F651uZnxw5TLTh3bvFUzkyGpGdEIZAqF5FWNhNrUmu2KytNuXc8Dr/6lemxP/OMqRy0q2KeoCXsRQK6SCubiTWpszaXLTMB7dgx6O01ixd2d8M779g3wBXzBC1hL5JyEWllM7Gmrg4OHTLLo3R1wenT5rjTCaWlZrKP15uSR7dZfqKYJ2gJe5Eeukgrm4k1y5ebnHlnJ8ycaZZOicfhAx8wm/4My6PbMD8hk5BEoZCALtLKZlGp5mZYvdrkz3t6oLzc7NrW3m7ur24N8qGfbuRLv1gBf/EXsGeP2UzCJvkJWYBLFAoJ6CKtbBaVCoXgvPNMb/yyy2DOHDh5EuL7gqz94T9w03/9FRe98WP8MyJmZ6DWVnjuOThxwjxAkecnZAEuUSgkhy5GlemiUsk1vwcHTerlwliQLdEvsfr0b/B2DeBwgHNGCe6edjNKGouZEdMDB8y6KzbIT8gCXKIQSA9dTFoy5bB3L1wQDfIPR+/kst7ncXjcOJ3gjg/iDveZAnUwv8PhofXJJT8hhCWkhy4mrb4e7ro+yPO3BVjT9RSz4214HVEi3jLiepB4LIozGh3Km9fUwKlTQ+uTb9gg3VshLCABXUxIauXhKk+Qm1q2cvFZfmb+WVPaG8alI+hIH4POEpzOQYiHTflLWRlEo2ZtgHvukUAuhIUkoIusJSsPL4gG+Z8tARa/9iTvai9VK1fS46ykzNGOIo4r0kfYXYmaMQMGE8XpM2fCmjWwaZMEcyEsJgFdZC0QMMH8w/u3MuDz43JCTGt8f9zO7IuWEt19jFjPAMrpYUYZuMNhWLjQ9MjXr5/q5gthWzIoKrIWCsGlLWYfz4ESPwO+SpwuRW/cR2W4jTkfW0f50vmUVnrxLKiCm26CpiYJ5kLkmPTQRdbq6qB0Z4iBKjPf/eSc85n31g68Xq+pXEmunyvF2ELklfTQRdYaGuCY28x31xpOOudycNbl+GepocoVCeZC5J300MWZxlk8q74efHc30LdlK+3tUFJVwYWXeClzLpVALsQUki3oxHDZ7CFns1UThShUsgWdmJjUxb1h7D3kZL67EAVFcuhiuNTdKpKKfPEsIaYL6aHnUMFnJNI1MLnSVrJnDrZYPEuI6WDcHrpSaqFS6gWl1AGl1H6l1KcSx2cppZ5VSh1K/PaP91jFIBiExka45Rbze6L7LhTCPg5jXstoDVy+XBb3FqJIjTsoqpSaB8zTWu9RSs0EdgM3Ap8ETmmt71VKfRbwa60/M9ZjFfqgaDbjgeNpbDyzo5u83dhoZavTG3ktpYeDLNkfYO05IWZdXGfWIvd40jewoaHAv1oIMb1YNiiqtT4OHE/83aOUOgAsAG4A1iZOexx4ERgzoBe6bMYDxzPV+0wmr2XpYJAPNH2JRW/+hhhOuk7UMatsEF55BdatS99AGewUoihllUNXSp0NrABeAWoSwR6t9XGlVLXlrcszK4NwNqnoXOTaQyFY6Q5yzQt3UvvODmLKTdzporzzbfhDD5SUwL59MG/eGQ0s+Ny/ECKtjKtclFIzgJ/BhJG9AAAPCklEQVQA/6y17s7i392qlNqllNrVntxkskBZudnvyH0m33gDXnzRxNDUfHZOcu3BIJ840sgNgZuZd3wPjniUmNtHFDd4vNDbS1/Uw7uH3uXZH3Xw4gtx2g+Zxr6xvGHKc/9CiInJKKArpdyYYP49rXVyN98Tifx6Ms/elu7faq0f1lqv0lqvqqqqsqLNOWPlZr+p+0wGg7B/vxlvrK8fHiRT0zyW7Jmc+IRYvqCDeFTjiIRx6ghqsI94HHxlLsIDMTqO9fPa/A/irPLjaz/Kb5v9vHH9Zr7fXG9te4QQeTNuykUppYBHgANa639Puetp4Gbg3sTvp3LSwjxKBuHUdMNkNtNJpqIbG+Gss9Ln5i3PtSc+Iar8fk4vqiR2sJ3BcBxfvI+Scg8eB/QMgC5x86crN9E211xcRwcEm6c+9y+EmLhMcujvBz4B/EkptS9x7POYQP4jpdQGIAR8NDdNzK9cjAeOFSQtL/tOebIZlyyD7mPw7gDEPeAGTp/mtKOG3669+71gntP2CCHyJpMql98BapS7141yfNpKHVD0eMzig3v3mpTLihUwd645LxkkGxpM+gWGl0pu2DDBBqRG5JoaU8nyu99BeztUVcFf/zU/ZRMHvfWkThzIWXuEEHkjU/8tlDrA6XbDSy+ZgdDzzoPubnP7+PHhufnUXPvRoxasPDtyICC5Nvmvf21GZB96iCs31Y86VmBFe6yanCWEyI6stmih1MlEL74I/f3meEkJLFsGe/bA4CDceGOWpYDZ1hFmcH6uShOtnJwlhDBktcUpkJor7+qC8vKhv2tq4NprTa83q5miTU2wZQtEIiZlMjBgIuZYETKDgYBczR2ycnKWECI7EtAtlJq+rqgY6qEnFy9M5qkz7h3fdx984QsmmPt8EA6bLd4uvLBgI6RUyQgxdSSHbqHU9PXSpSZv3t1t/k4eX748g4lEwSB89KPwuc9Bfz8xh5vBvijhN49y8p1eTh9sKdgIaeXkLCFEdiSgWyh1QDESgTVrYO1a83dycLG5eZyJRMkk9Pbt4HQSVw70wCAaB9rhpLSnnc4/t9PqLcwIaeXkLCFEdiTlYrHxctP33z88JXH+/ibe/7t7qTz1JjzkhlmzTFXKwAB4PESiDpwqjCs+SNRVgjs6AC43Ad3AptxfTtasnpwlhMicBHSLZJoXT82zX/b7+7j65S/iCA8SUW66OzSl7YeJnerB6/WC1mgdI+Z044xFcEYHiDvd/Hbt3ewKF26ElMUahZgaknKxQDYLbCVTEuf+9D7W/eZzuMM9OIjgIoY3HiaGg3j7Kfq9laA1MZeHOE7iDhcRdynPr/kiOxesl5y0EOIM0kO3QMalesEg9YEA9z7/M6pa9uIg/t4UXJceJBL1oh1OXETpOA0l69bhfnkH0Y4ox2ZdyI6rPsvOBevzMnNTltAVovhIQLdARqV6990HX/sa0Z4+qvt7gaH1FBQajcJFmEjcTZ+3gned1VSXl+PZ9Pe8tbyB7zfXm+Dqz31OOnVyUOo3js2bzf0S6IUoTBLQLTDaglarPEFoDJg5/zt2gM9HJKrwoFFAnKGcl0KDqWXhkHMpr974AMseMpFyCdC4Pn/XM9o3jm3boLc3faCXoC7E1JMcugXSleqV/TnITS2JxPqRI6A1RCI4opFE2DYvfgxSEi+KXWVX8X9mfZMrN01dhAyFhiZDJVVUwM6dFq/dLoSwlAR0C6Rb0Or2hQH85yYiXk+PmekJOJQmlvhipIEYHiJ4GMTLV2f9G/964bOc9ZH6Ke3xjjY5SOv0gb5A5zgJMe1IymWC0g0aDluj5ZYQVCUS6+XlJqhHIjhcEIu6iMXjOIgRxkM/pfxi+ac5cc0dLO2AjRtz075MPyRGW0J39Wrzt6yVLkRhkh76BKSWKa50B7nsl410NtxC68bGoVrF1G7upZe+t5St0+fFVeIEp5O3/Ct56b/dwcPrn+WpRXfwxz+apQICgcktOTvZfUpHW0J30yaZBSpEIZPlcycguUzu5ceaWPPbLThjEbrcVfTNruWiFc6hcpDUdWR37zY/bjcsWgS33QbrzUin1UvOpi7jm5S8ndVKj2lIOaMQ+SfL5+ZQKGR65mte3gIo+kqr8EUH8LY0Q/1yE/EaG4fPgb/kEvjKV9JGP6uXnM3liocyC1SIwiUBfQLq6mDRLwM44xH6SqtAKQYooaQETr9+lEOvefmPENTV1dPQMP4Ap9UBWPYFFWJ6khz6BDQ0QNm7Ibo8VTijA0QiEI2Ct8JH1+F2Wj11WeWurV5yVlY8FGJ6koA+njQbZNbXw5IP1dHnX4DuH6CEfhbWaqLvdqHdbt5c0ZBVnbbVAdjyfUqFEEVBBkXHMtZoJZj7olFoaYH2dkLH3fx+3d0cXD40rTMeN0H10UfHfyoZbBRCpCODohPwRlOQlgcDuFpCRBfU8b7qE8yZN8poZeqgp88HV1/Nz1obOOitJyV1nXHqRAYbhRCTJQE94Y2mIG2f3ooq9xOdV4vq7CC6+1ne/fA6ZqdG6NTRyhFR+Mog7EwzISfXKyMKIQRIQH8v1zHjoadw4+HkrBX0OhxQ6ae/bDaR7fuYfeG8ofPH6HLnY7ceSc0IIUYzvQN6So48MqhxlWoWHt3BO7WX0ztjLu3zL+asw8+ZbnaGXe5cpk7GWtZWgroQYnpXuaTM6IlXVBKLKaJOH3NOvg5AX9zH20s+WDDlIqkTkGS1QyHESNO7h54yo6f80mX0PrudqMeLN9YJnR24ujuo/NpmWF8Y3d9czgAVQhS/6d1DT5nRM/uCGso+dAVOlyIcBl3pp/prm1lSIMEcrJ+AJISwl0kFdKXUh5VSB5VSh5VSn7WqUXkzYkbP7HkeFq5bSvjh/+SltY3c+4v65FyigiAzQIUQY5lwQFdKOYFvAtcBFwA3KaUusKpheZFmSuUb12/mS0/XT3jp2Tw3VwZEhRDvmUwO/VLgsNb6CIBS6gngBuA1KxqWNyPKUr7faO3Kh1aTCUhCiNFMJuWyAHgn5fbRxLGiNtp+mjLwKIQodJMJ6CrNsTMWhlFK3aqU2qWU2tXe3j6Jp8sPGXgUQhSryQT0o8DClNu1wLGRJ2mtH9Zar9Jar6qqqprE0+VHLgYe0yzYKIQQlptMQP8DsFgpdY5SygN8HHjammZNHasHHie7v6cQQmRqwoOiWuuoUuo24BnACTyqtd5vWcvSaWqCBx80y9UuWDBsX04rWTnwaPX2ckIIMZpJzRTVWv8C+IVFbRlbUxN8+tNQXg7z5kFnp7kNOQnqVpHZnUKIfCmemaIPPmiCeWWlWcikstLcfvDBqW7ZmGSQVQiRL8UT0FtaTABPVV5ujhcwmd0phMiX4gnoCxZAd/fwY93d5ngBk9mdQoh8KZ7VFm+7bShnXl5ugnl3N9x119S2KwMyu1MIkQ/FE9CTA5+pVS533VXQA6JCCJFPxRPQwQRvCeBCCJFW8eTQhRBCjEkCuhBC2ERxpVyyFAyaGZmhkKn7bmiQwUkhhH3Ztocua6gIIaYb2wb01DVUHI6hvwOBqW6ZEELkhm0DumxUIYSYbmwb0GUNFSHEdGPbgC5rqAghphvbBnRZQ0UIMd3YumxR1lARQkwntu2hCyHEdGPrHnq2ZCKSEKKYSQ89QSYiCSGKnQT0BJmIJIQodhLQE2QikhCi2ElAT5CJSEKIYicBPUEmIgkhip0E9ASZiCSEKHZStphCJiIJIYqZ9NCFEMImJKALIYRNSEAXQgibkIAuhBA2IQFdCCFsQmmt8/dkSrUDb+ftCY05wMk8P2e+yTXax3S4TrnG7J2lta4a76S8BvSpoJTapbVeNdXtyCW5RvuYDtcp15g7knIRQgibkIAuhBA2MR0C+sNT3YA8kGu0j+lwnXKNOWL7HLoQQkwX06GHLoQQ04JtA7pS6sNKqYNKqcNKqc9OdXusoJRaqJR6QSl1QCm1Xyn1qcTxWUqpZ5VShxK//VPd1slSSjmVUnuVUj9L3D5HKfVK4hp/qJTyTHUbJ0spVamUalJKvZ54Ty+323uplPqXxP/VZqXUD5RSPju8l0qpR5VSbUqp5pRjad87ZTyQiEVBpdTKXLXLlgFdKeUEvglcB1wA3KSUumBqW2WJKHCH1noZsBr4x8R1fRZ4Tmu9GHgucbvYfQo4kHL7q8DXE9fYAWyYklZZ6xvAr7TW5wMXYa7XNu+lUmoBcDuwSmu9HHACH8ce7+V3gA+PODbae3cdsDjxcyuwLVeNsmVABy4FDmutj2itw8ATwA1T3KZJ01of11rvSfzdgwkACzDX9njitMeBG6emhdZQStUCfwV8O3FbAdcATYlT7HCN5cBVwCMAWuuw1roTm72XmCW6S5RSLqAUOI4N3kut9cvAqRGHR3vvbgD+Uxs7gUql1LxctMuuAX0B8E7K7aOJY7ahlDobWAG8AtRorY+DCfpA9dS1zBL3A58G4onbs4FOrXU0cdsO7+e5QDvwWCK19G2lVBk2ei+11i3AViCECeRdwG7s914mjfbe5S0e2TWgqzTHbFPOo5SaAfwE+GetdfdUt8dKSqmPAG1a692ph9OcWuzvpwtYCWzTWq8Aeini9Eo6iRzyDcA5wHygDJN+GKnY38vx5O3/r10D+lFgYcrtWuDYFLXFUkopNyaYf09rHUgcPpH8Cpf43TZV7bPA+4HrlVJvYVJl12B67JWJr+1gj/fzKHBUa/1K4nYTJsDb6b38IPCm1rpdax0BAsAV2O+9TBrtvctbPLJrQP8DsDgxmu7BDMQ8PcVtmrRELvkR4IDW+t9T7noauDnx983AU/lum1W01p/TWtdqrc/GvG/Pa63/FngBWJ84raivEUBr3Qq8o5Ramji0DngNG72XmFTLaqVUaeL/bvIabfVephjtvXsa+F+JapfVQFcyNWM5rbUtf4C/BN4A/gzcOdXtseiarsR8VQsC+xI/f4nJMT8HHEr8njXVbbXoetcCP0v8fS7wKnAY+DHgner2WXB9FwO7Eu/nk4Dfbu8l8EXgdaAZ+C7gtcN7CfwAMy4QwfTAN4z23mFSLt9MxKI/Yap+ctIumSkqhBA2YdeUixBCTDsS0IUQwiYkoAshhE1IQBdCCJuQgC6EEDYhAV0IIWxCAroQQtiEBHQhhLCJ/w9rKb1jSIbqlgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1a3772b25c0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x[:,0], x[:,1], color='b', alpha=0.5)\n",
    "plt.scatter(x_restore[:,0], x_restore[:,1], color='r', alpha=0.5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# scikit-learn中的PCA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.decomposition import PCA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PCA(copy=True, iterated_power='auto', n_components=1, random_state=None,\n",
       "  svd_solver='auto', tol=0.0, whiten=False)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca = PCA(n_components=1)\n",
    "pca.fit(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.76961077, -0.63851333]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca.components_\n",
    "# 结果和我们自己封装的类的结果不一样,\n",
    "# 我们封装用的是梯度上升法求解\n",
    "# sklearn中是用其他方法, 所以结果的方向不一致"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 1)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_reduction = pca.transform(x)\n",
    "x_reduction.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(100, 2)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_restore = pca.inverse_transform(x_reduction)\n",
    "x_restore.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1a378c4a9b0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x[:,0], x[:,1], color='b', alpha=0.5)\n",
    "plt.scatter(x_restore[:,0], x_restore[:,1], color='r', alpha=0.5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
